﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Web;

namespace TSharp.Core.Mvc.Web
{
    /// <summary>
    ///     区域语言提供器实现
    ///     <para>2010/10/26</para>
    ///     <para>TANGJINGBO</para>
    ///     <author>tangjingbo</author>
    /// </summary>
    public class SiteProvider : ISiteProvider
    {
        /// <summary>
        ///     区域语言选项的cookie标识
        /// </summary>
        public static string CultureCookieKey = "tsharp_Lang";

        /// <summary>
        ///     区域语言选项的Session标识
        /// </summary>
        public static string CultureSessionKey = "tsharp_CultureSessionKey";

        /// <summary>
        ///     主题Session键
        /// </summary>
        public static string ThemeSessionKey = "tsharp_ThemeSessionKey";

        /// <summary>
        ///     主题Cookie键
        /// </summary>
        public static string ThemeCookieKey = "tsharp_theme";

        /// <summary>
        ///     主题和语言Cookie有效期限（小时）
        /// </summary>
        public static int Lang_Theme_CookieExpiresHours = 7*24;

        private static readonly IEnumerable<Culture> allCultureInfo;
        private static readonly IEnumerable<Theme> allTheme;

        static SiteProvider()
        {
            try
            {
                //   LogHelper a;
                allCultureInfo = SiteConfig.Instance.Cultures.OrderBy(x => x.Order);
                allTheme = SiteConfig.Instance.Themes.OrderBy(x => x.Order);
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        ///     根据Name获取区域语言对象
        /// </summary>
        /// <param name="cultureName">Name of the culture.</param>
        /// <returns></returns>
        public CultureInfo GetCultureInfo(string cultureName)
        {
            if (!string.IsNullOrEmpty(cultureName))
                try
                {
                    var ci = new CultureInfo(cultureName);
                    if (ci.IsNeutralCulture)
                        ci = new CultureInfo(ci.KeyboardLayoutId);
                    return ci;
                }
                catch
                {
                    return CultureInfo.CurrentUICulture;
                }
            return CultureInfo.CurrentUICulture;
        }

        /// <summary>
        ///     获取当前请求默认语言
        /// </summary>
        /// <returns></returns>
        public CultureInfo GetCurrentCultureInfo()
        {
            HttpContextBase context = AopContext.GetHttpContext();
            if (context.Session != null)
            {
                var cultureInfo = context.Session[CultureSessionKey] as CultureInfo;
                // 判断Session中是否有值，没有就设置默认值  
                if (cultureInfo == null)
                {
                    string langName = "";
                    HttpCookie cLang = context.Request.Cookies[CultureCookieKey];
                    if (cLang != null)
                    {
                        langName = cLang.Value;
                    }
                    else if (context.Request.UserLanguages != null && context.Request.UserLanguages.Length != 0)
                    {
                        langName = context.Request.UserLanguages[0];
                    }
                    cultureInfo = GetCultureInfo(langName);
                    context.Session[CultureSessionKey] = cultureInfo;
                }
                return cultureInfo;
            }
            return CultureInfo.CurrentUICulture;
        }

        /// <summary>
        ///     设置当前请求的Cookie，Session以及线程的区域语言设置
        /// </summary>
        /// <param name="ci">The ci.</param>
        public void SetCurrentCultureInfo(CultureInfo ci)
        {
            HttpContextBase context = AopContext.GetHttpContext();

            var cookie = new HttpCookie(CultureCookieKey, ci.Name);
            cookie.Expires = DateTime.Now.AddHours(Lang_Theme_CookieExpiresHours);
            context.Response.Cookies.Add(cookie);
            context.Session[CultureSessionKey] = ci;
            SetThreadCulture(ci);
        }

        /// <summary>
        ///     设置当前请求的Cookie，Session以及线程的区域语言设置
        /// </summary>
        /// <param name="CultureName">Name of the culture.</param>
        public void SetCurrentCultureInfo(string CultureName)
        {
            HttpContextBase context = AopContext.GetHttpContext();
            CultureInfo ci = GetCultureInfo(CultureName);
            SetCurrentCultureInfo(ci);
        }

        /// <summary>
        ///     是否启用多语言
        /// </summary>
        /// <value>
        ///     <c>true</c> if [enable culture]; otherwise, <c>false</c>.
        /// </value>
        public bool EnableCulture
        {
            get { return SiteConfig.Instance.EnableCulture; }
        }

        /// <summary>
        ///     获取站点所有可用语言
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Culture> GetAllCultureInfo()
        {
            return allCultureInfo;
        }

        /// <summary>
        ///     是否启用主题
        /// </summary>
        /// <value>
        ///     <c>true</c> if [enable theme]; otherwise, <c>false</c>.
        /// </value>
        public bool EnableTheme
        {
            get { return SiteConfig.Instance.EnableTheme; }
        }

        /// <summary>
        ///     获取所有可用主题
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Theme> GetAllTheme()
        {
            return allTheme;
        }

        /// <summary>
        ///     获取当前请求主题
        /// </summary>
        /// <returns></returns>
        /// <value>
        ///     <c>true</c> if [enable theme]; otherwise, <c>false</c>.
        /// </value>
        public Theme GetCurrentTheme()
        {
            HttpContextBase context = AopContext.GetHttpContext();
            if (context.Session != null)
            {
                var theme = context.Session[ThemeSessionKey] as Theme;
                // 判断Session中是否有值，没有就设置默认值  
                if (theme == null)
                {
                    string themeName = "";
                    HttpCookie cLang = context.Request.Cookies[ThemeCookieKey];
                    if (cLang != null)
                        themeName = cLang.Value;
                    theme = GeThemeInfo(themeName);
                    context.Session[ThemeSessionKey] = theme;
                }
                return theme;
            }
            return SiteConfig.Instance.ThemeDefault;
        }

        /// <summary>
        ///     设置当前请求主题
        /// </summary>
        /// <param name="theme">The theme.</param>
        public void SetCurrentTheme(Theme theme)
        {
            HttpContextBase context = AopContext.GetHttpContext();
            var cookie = new HttpCookie(ThemeCookieKey, theme.Name);
            cookie.Expires = DateTime.Now.AddHours(Lang_Theme_CookieExpiresHours);
            context.Response.Cookies.Add(cookie);
            context.Session[ThemeSessionKey] = theme;
        }


        /// <summary>
        ///     设置当前请求主题
        /// </summary>
        /// <param name="themeName">Name of the theme.</param>
        public void SetCurrentTheme(string themeName)
        {
            Theme theme = GeThemeInfo(themeName);
            SetCurrentTheme(theme);
        }

        /// <summary>
        ///     设置线程区域语言
        /// </summary>
        /// <param name="ci">The ci.</param>
        public static void SetThreadCulture(CultureInfo ci)
        {
            if (!ci.IsNeutralCulture)
            {
                Thread.CurrentThread.CurrentUICulture = ci;
                Thread.CurrentThread.CurrentCulture = ci;
            }
        }

        private Theme GeThemeInfo(string themeName)
        {
            Theme theme = SiteConfig.Instance.Themes.Find(x => x.Name == themeName);
            return theme ?? SiteConfig.Instance.ThemeDefault;
        }
    }
}